using System;
using System.Collections.Generic;
using UnityEngine;

public class Inventory_Base : MonoBehaviour, ISaveable
{
    public event Action OnInventoryChange;
    [Header("Item Data Base")]
    [SerializeField] protected ItemListDataSO itemDataBase;
    [SerializeField] protected float maxInventoryCount = 12;
    public List<Inventory_Item> itemList = new();
    protected Player player;
    public Inventory_Storage storage { get; private set; }
 
    protected virtual void Awake()
    {
        storage = FindFirstObjectByType<Inventory_Storage>();
        player = GetComponent<Player>();
    }
    public bool HasEnoughDeliveryItem(Inventory_Item[] itemsToCheck)
    {
        for (int i = 0; i < itemsToCheck.Length; i++)
        {
            if (HasEnoughDeliveryItem(itemsToCheck[i]) == false)
                return false;
        }
        return true;
    }
    public bool HasEnoughDeliveryItem(Inventory_Item itemToCheck)
    {
        int totalStackSize = 0;
        foreach (var item in itemList)
        {
            if (item.itemData == itemToCheck.itemData)
                totalStackSize += item.stackSize;
        }
        foreach (var item in storage.materialStorageList)
        {
            if (item.itemData == itemToCheck.itemData)
                totalStackSize += item.stackSize;
        }
        return totalStackSize >= itemToCheck.stackSize;
    }
    public  void RemoveItemAmount(Inventory_Item itemToRemove)
    {
        int amount = itemToRemove.stackSize;

        for (int i = 0; i < itemList.Count; i++)
        {
            Inventory_Item itemInlist = itemList[i];
            if (itemInlist.itemData == itemToRemove.itemData)
            {
                int removeCount = Mathf.Min(amount, itemInlist.stackSize);

                for (int j = 0; j < removeCount; j++)
                {
                    RemoveOneItemInOneSlot(itemInlist);
                    if (amount < 0) return;
                    amount--;
                }
            }
        }
        for (int i = 0; i < storage.materialStorageList.Count; i++)
        {
            Inventory_Item itemInlist = storage.materialStorageList[i];

            if (itemInlist.itemData == itemToRemove.itemData)
            {
                int removeCount = Mathf.Min(amount, itemInlist.stackSize);
                for (int j = 0; j < removeCount; j++)
                {
                    storage.RemoveOneItemInOneSlot(itemInlist, storage.materialStorageList);
                    if (amount < 0) return;
                    amount--;
                }
            }
        }
    }
    //尝试使用消耗品
    public void TryUseConsumable(Inventory_Item consumable)
    {
        if (consumable == null || consumable.itemEffect == null || consumable.itemEffect.CanUserBuff(player) == false)
        {
            OnInventoryChange?.Invoke();
            return;
        }
        consumable.itemEffect?.ApplyEffect();

        if (consumable.stackSize > 1)
            consumable.ReduceStackSize();
        else
            itemList.Remove(consumable);
        OnInventoryChange?.Invoke();
    }

    public bool CanAddItem(Inventory_Item itemToAdd)
    {
        bool canStack = FindCanStackInventorySlot(itemToAdd) != null;

        return itemList.Count < maxInventoryCount || canStack;
    }

    //添加物品
    public void AddItem(Inventory_Item itemToAdd)
    {
        //查找库存的能够叠加的卡槽
        Inventory_Item slot = FindCanStackInventorySlot(itemToAdd);

        //判断物品是否为空，判断物品是否能够叠加
        if (slot != null)
            slot.AddStackSize(); //添加叠加
        else
            itemList.Add(itemToAdd); //添加进物品列表

        OnInventoryChange?.Invoke();
        storage.OnTriggerUpdateUI();
    }
    //移除一个卡槽的所有的物品
    public void RemoveAllItemInOneSlot(Inventory_Item itemToRemove)
    {
        for (int i = 0; i < itemToRemove.stackSize; i++)
            RemoveOneItemInOneSlot(itemToRemove);
    }

    //移除单个物品,默认为移除itemList的物品数据
    public virtual void RemoveOneItemInOneSlot(Inventory_Item itemToRemove,List<Inventory_Item> list = null)
    {
        List<Inventory_Item> needToRemoveList = list == null ? itemList : list;
        Inventory_Item itemInIverntory = FindInventoryItem(itemToRemove, needToRemoveList);

        if (itemInIverntory == null)
            return;

        if (itemInIverntory.stackSize > 1)
            itemInIverntory.ReduceStackSize();
        else
            itemList.Remove(itemToRemove);

        OnInventoryChange?.Invoke();
        storage.OnTriggerUpdateUI();
    }

    //查找已经拥有的库存物品，指定所查找的列表
    public virtual Inventory_Item FindInventoryItem(Inventory_Item itemToFind,List<Inventory_Item> list) =>
                                    list.Find(target => target.itemData == itemToFind.itemData);
    public Inventory_Item FindItem(Inventory_Item itemToFind) => itemList.Find(target => target == itemToFind);

    //查找库存中能够叠加的物品对象
    public Inventory_Item FindCanStackInventorySlot(Inventory_Item itemToFind) =>
        itemList.Find(target => target.itemData == itemToFind.itemData && target.CanAddStackSize());

    public void OnTriggerUpdateUI() => OnInventoryChange?.Invoke();

    public virtual void SaveData(ref GameData gameData) { }

    public virtual void LoadData(GameData gameData) { }
}
